/*
 * chapter_15.cpp
 *
 *  Created on: 2020年12月8日
 *      Author: san
 */

#include <iostream>
#include <fstream>
#include <vector>
#include <memory>
#include <functional>

#include "Quote.h"
#include "Bulkquote.h"
#include "WordQuery.h"
#include "Query.h"
#include "NotQuery.h"
#include "AndQuery.h"
#include "OrQuery.h"
#include "TextQuery.h"

using std::vector;

double print_total(std::ostream &os, const Quote &item, size_t n)
{
	os << item.isbn() << ": " << item.net_price(n) << std::endl;
}

void t15_6()
{
	Quote q1("Y0001", 15.0);
	Bulk_quote bq("Y0002", 4.9, 2, 0.9);
	print_total(std::cout, q1, 10);
	print_total(std::cout, bq, 2);
}

void t15_11()
{
	Quote q1("Y0001", 15.0);
	Bulk_quote bq("Y0002", 4.9, 2, 0.9);
	q1.debug(); bq.debug();
}

void t15_17()
{
//	Disc_quote dq;  不可实例化
}

void t15_21()
{
	// shapes and rectangle
	Rectangle rec(5.0, 4.6, "REctangle");
	std::cout << "name: " << rec.getName() << " area: " << rec.area() << std::endl;
}

void t15_23()
{
//	 就是虚调用和静态绑定的关系，不写了
}

void t15_25()
{
	// 删除基类的默认构造函数，观察派生类的默认构造过程
	// 1. 合成的Bulk默认构造函数，先运行Disc的默认构造函数，后又运行Quote的默认构造函数
	// 2. Quote的默认将bookNo初始化为空字符串，price初始化为0
	// 3. Quote的构造函数完成后，继续执行Disc的构造函数，它使用类内初始值初始化qty和discount
	// 4. Disc的构造函数完成后，继续执行Bulk的构造函数，但是它什么具体工作也不做

	// Quote() -> Disc_quote() -> Bulk_quote()
	Bulk_quote bq;  // 无法生成默认构造函数
}

void t15_26()
{
	std::cout << "---------------" << std::endl;
//	Quote q("Y0001", 36.00);
	Bulk_quote bq1("Gone with the Wind", 36.00, 2, 0.9);
	Bulk_quote bq2(bq1);

}

void t15_27()
{
	std::cout << "---------------" << std::endl;
//	Quote q("Y0001", 36.00);

	// 与15.26不同的是，这里是直接继承的
	Bulk_quote bq1("Gone with the Wind", 36.00, 2, 0.9);
	Bulk_quote bq2(bq1);
}

void t15_28()
{
	// vector<Quote>
	vector<Quote> qvec;
	Bulk_quote bq1("Gone with the Wind", 36.00, 2, 0.9);
	for (int i = 0; i < 5; ++i)
	{
		qvec.push_back(bq1);
	}

	double amount = 0.0;
	for (auto v: qvec)
	{
		amount += v.net_price(10);
	}

	std::cout << "amount: " << amount << std::endl;
}

void t15_29()
{
	// vector<Quote>
	vector<std::shared_ptr<Quote>> qvec;
	Bulk_quote bq1("Gone with the Wind", 36.00, 2, 0.9);
	for (int i = 0; i < 5; ++i)
	{
		qvec.push_back(std::make_shared<Bulk_quote>(bq1));
	}

	double amount = 0.0;
	for (auto v: qvec)
	{
		amount += v->net_price(10);
	}

	std::cout << "amount: " << amount << std::endl;
}

void t15_36()
{
	Query q = Query("first") | Query("second") & ~Query("Third");
	std::cout << q;
//	Query q1 = ~q;

}

void t15_39()
{
	using QueryResult = TextQuery::QueryResult;
	std::ifstream in("/home/san/eclipse-workspace/CppPrimer/file/alibaba.txt");
	TextQuery tq(in);
	Query q = Query("robbers") & Query("the") & Query("captain");
	QueryResult result = q.eval(tq);
	print(std::cout, result);
}

void t15_39_1()
{
	/*
	 * 查询单词出现次数
	 */
	using QueryResult = TextQuery::QueryResult;
	string word;
	std::ifstream infile("/home/san/eclipse-workspace/CppPrimer/file/alibaba.txt");
	std::cout << "请输入需要查询的单词：" << std::endl;
	TextQuery tq(infile);
	while (std::cin >> word && "0" != word)
	{
//		TextQuery tq(infile);
		QueryResult result = tq.query(word);
		print(std::cout, result);
	}
}

int main15()
{
	t15_6();
	std::cout << "-------------------虚函数----------------------" << std::endl;
	t15_11();

	std::cout << "-----------------派生类向基类转换的可访问性-------------------" << std::endl;
	t15_21();

	std::cout << "-----------------继承中的类作用域-------------------" << std::endl;
	t15_23();

	std::cout << "-----------------合成的拷贝构造与控制-------------------" << std::endl;
	t15_25();

	std::cout << "-----------------派生类的拷贝控制成员-------------------" << std::endl;
	t15_26();

	std::cout << "-----------------继承的构造函数------------------" << std::endl;
	t15_27();

	std::cout << "-----------------容器和继承------------------" << std::endl;
	t15_28();
	t15_29();  // 这两次结果不一样， 原因是vector时对象发生了转换

	std::cout << "-----------------编写Basket类------------------" << std::endl;

	std::cout << "-----------------文本查询程序------------------" << std::endl;
	t15_36();
	t15_39();
	t15_39_1();  // 是正确的
	return 0;
}


